#if PLATFORM == PLATFORM_WIN32
#	include <windows.h>
#	include "glew/glew.h"
#	include "glew/wglew.h"
#endif

#include "render/rendertypes.h"
#include "mathlib/mat4.h"

namespace rengine3d {

	// Helper OpenGL convertations functions

	void MakeGLMatrix(GLfloat gl_matrix[16], const CMat4& m) {
		size_t x = 0;
		for (size_t i = 0; i < 4; i++) {
			for (size_t j = 0; j < 4; j++) {
				gl_matrix[x] = m[j][i];
				x++;
			}
		}
	}

	GLenum GetGLTextureParamEnum(textureParam_t type) {
		switch(type) {
		case textureParam_ColorFunc:		return GL_COMBINE_RGB_ARB;
		case textureParam_AlphaFunc:		return GL_COMBINE_ALPHA_ARB;
		case textureParam_ColorSource0:		return GL_SOURCE0_RGB_ARB;
		case textureParam_ColorSource1:		return GL_SOURCE1_RGB_ARB;
		case textureParam_ColorSource2:		return GL_SOURCE2_RGB_ARB;
		case textureParam_AlphaSource0:		return GL_SOURCE0_ALPHA_ARB;
		case textureParam_AlphaSource1:		return GL_SOURCE1_ALPHA_ARB;
		case textureParam_AlphaSource2:		return GL_SOURCE2_ALPHA_ARB;
		case textureParam_ColorOp0:			return GL_OPERAND0_RGB_ARB;
		case textureParam_ColorOp1:			return GL_OPERAND1_RGB_ARB;
		case textureParam_ColorOp2:			return GL_OPERAND2_RGB_ARB;
		case textureParam_AlphaOp0:			return GL_OPERAND0_ALPHA_ARB;
		case textureParam_AlphaOp1:			return GL_OPERAND1_ALPHA_ARB;
		case textureParam_AlphaOp2:			return GL_OPERAND2_ALPHA_ARB;
		case textureParam_ColorScale:		return GL_RGB_SCALE_ARB;
		case textureParam_AlphaScale:		return GL_ALPHA_SCALE;	
		}

		return 0;
	}

	GLenum GetGLTextureFuncEnum(textureFunc_t type)	{
		switch(type) {
		case textureFunc_Modulate:		return GL_MODULATE;
		case textureFunc_Replace:		return GL_REPLACE;
		case textureFunc_Add:			return GL_ADD;
		case textureFunc_Substract:		return GL_SUBTRACT_ARB;
		case textureFunc_AddSigned:		return GL_ADD_SIGNED_ARB;
		case textureFunc_Interpolate:	return GL_INTERPOLATE_ARB;
		case textureFunc_Dot3RGB:		return GL_DOT3_RGB_ARB;
		case textureFunc_Dot3RGBA:		return GL_DOT3_RGBA_ARB;
		}
		return 0;
	}

	GLenum GetGLTextureSourceEnum(textureSource_t type) {
		switch(type) {
		case textureSource_Texture:		return GL_TEXTURE;
		case textureSource_Constant:	return GL_CONSTANT_ARB;
		case textureSource_Primary:		return GL_PRIMARY_COLOR_ARB;
		case textureSource_Previous:	return GL_PREVIOUS_ARB;
		}
		return 0;
	}

	GLenum GetGLTextureOpEnum(textureOp_t type) {
		switch(type) {
		case textureOp_Color:			return GL_SRC_COLOR;
		case textureOp_OneMinusColor:	return GL_ONE_MINUS_SRC_COLOR;
		case textureOp_Alpha:			return GL_SRC_ALPHA;
		case textureOp_OneMinusAlpha:	return GL_ONE_MINUS_SRC_ALPHA;
		}
		return 0;
	}

	GLenum GetGLDepthTestFuncEnum(depthTestFunc_t type) {
		switch(type) {
		case depthTestFunc_Never:			return GL_NEVER;
		case depthTestFunc_Less:			return GL_LESS;
		case depthTestFunc_LessOrEqual:		return GL_LEQUAL;
		case depthTestFunc_Greater:			return GL_GREATER; 
		case depthTestFunc_GreaterOrEqual:	return GL_GEQUAL;
		case depthTestFunc_Equal:			return GL_EQUAL;
		case depthTestFunc_NotEqual:		return GL_NOTEQUAL;
		case depthTestFunc_Always:			return GL_ALWAYS; 
		}
		return 0;
	}

	GLenum GetGLAlphaTestFuncEnum(alphaTestFunc_t type)	{
		switch(type) {
		case alphaTestFunc_Never:			return GL_NEVER;
		case alphaTestFunc_Less:			return GL_LESS;
		case alphaTestFunc_LessOrEqual:		return GL_LEQUAL;
		case alphaTestFunc_Greater:			return GL_GREATER; 
		case alphaTestFunc_GreaterOrEqual:	return GL_GEQUAL;
		case alphaTestFunc_Equal:			return GL_EQUAL;
		case alphaTestFunc_NotEqual:		return GL_NOTEQUAL;
		case alphaTestFunc_Always:			return GL_ALWAYS; 
		}
		return 0;
	}

	GLenum GetGLStencilFuncEnum(stencilFunc_t type) {
		switch(type) {
		case stencilFunc_Never:				return GL_NEVER;
		case stencilFunc_Less:				return GL_LESS;
		case stencilFunc_LessOrEqual:		return GL_LEQUAL;
		case stencilFunc_Greater:			return GL_GREATER; 
		case stencilFunc_GreaterOrEqual:	return GL_GEQUAL;
		case stencilFunc_Equal:				return GL_EQUAL;
		case stencilFunc_NotEqual:			return GL_NOTEQUAL;
		case stencilFunc_Always:			return GL_ALWAYS; 
		}
		return 0;
	}

	GLenum GetGLStencilOpEnum(stencilOp_t type) {
		switch(type)
		{
		case stencilOp_Keep:			return GL_KEEP; 
		case stencilOp_Zero:			return GL_ZERO; 
		case stencilOp_Replace:			return GL_REPLACE; 
		case stencilOp_Increment:		return GL_INCR; 
		case stencilOp_Decrement:		return GL_DECR;
		case stencilOp_Invert:			return GL_INVERT;
		case stencilOp_IncrementWrap:	return GL_INCR_WRAP_EXT;
		case stencilOp_DecrementWrap:	return GL_DECR_WRAP_EXT;
		}
		return 0;
	}

	GLenum GetGLBlendEnum(blendFunc_t type) {
		switch(type)
		{
		case blendFunc_Zero:					return GL_ZERO;
		case blendFunc_One:						return GL_ONE;
		case blendFunc_SrcColor:				return GL_SRC_COLOR;
		case blendFunc_OneMinusSrcColor:		return GL_ONE_MINUS_SRC_COLOR;
		case blendFunc_DestColor:				return GL_DST_COLOR;
		case blendFunc_OneMinusDestColor:		return GL_ONE_MINUS_DST_COLOR;
		case blendFunc_SrcAlpha:				return GL_SRC_ALPHA;
		case blendFunc_OneMinusSrcAlpha:		return GL_ONE_MINUS_SRC_ALPHA;
		case blendFunc_DestAlpha:				return GL_DST_ALPHA;
		case blendFunc_OneMinusDestAlpha:		return GL_ONE_MINUS_DST_ALPHA;
		case blendFunc_SrcAlphaSaturate:		return GL_SRC_ALPHA_SATURATE;
		}
		return 0;
	}


}


